
const isDef = (val) => {
  return typeof val !== 'undefined'
}
const isUnDef = (val) => {
  return !isDef(val)
}
const isNull = (val) => {
  return val === null
}
const isNullOrUnDef = (val) => {
  return isUnDef(val) || isNull(val)
}

// 简单加密密钥
const cacheCipher = {
  key: '_11111000001111@',
  iv: '@11111000001111_',
}

// 简单加密类 - 替代AesEncryption
class SimpleEncryption {
  constructor({ key, iv }) {
    this.key = key;
    this.iv = iv;
  }

  // 使用XOR算法进行简单加密
  encryptByAES(data) {
    return this.xorEncrypt(data, this.key);
  }

  // 使用XOR算法进行解密
  decryptByAES(data) {
    return this.xorDecrypt(data, this.key);
  }

  // XOR加密实现
  xorEncrypt(str, key) {
    let result = '';
    for (let i = 0; i < str.length; i++) {
      result += String.fromCharCode(str.charCodeAt(i) ^ key.charCodeAt(i % key.length));
    }
    // 使用 encodeURIComponent 和 btoa 处理 Unicode 字符
    return btoa(encodeURIComponent(result));
  }

  // XOR解密实现
  xorDecrypt(str, key) {
    try {
      // 先解码Base64，再解码URI组件
      let decoded = decodeURIComponent(atob(str));
      let result = '';
      for (let i = 0; i < decoded.length; i++) {
        result += String.fromCharCode(decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
      }
      return result;
    } catch (e) {
      // 如果解密失败，返回空字符串或其他适当的默认值
      return '';
    }
  }
}

const createStorage = ({
  prefixKey = '',
  storage = 'sessionStorage',
  key = cacheCipher.key,
  iv = cacheCipher.iv,
  timeout = 60 * 60 * 24 * 1,
  hasStruct = true,
  hasEncrypt = true,
}) => {
  if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) {
    throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!')
  }

  const encryption = new SimpleEncryption({ key, iv })

  /**
   * 缓存类
   * 构造参数可以传入sessionStorage、localStorage
   */
  const WebStorage = class WebStorage {
    storage
    prefixKey
    encryption
    hasStruct
    hasEncrypt
    /**
     *
     * @param {*} 缓存
     */
    constructor() {
			if(storage === 'sessionStorage') {
				this.storage = sessionStorage
			}
      else {
				this.storage = localStorage
			}
      this.prefixKey = prefixKey
      this.encryption = encryption
      this.hasStruct = hasStruct
      this.hasEncrypt = hasEncrypt
    }

    getKey(key) {
      return `${this.prefixKey}${key}`.toUpperCase()
    }

    /**
     * 设置缓存
     * @param {string} key
     * @param {any} value
     * @param {number} expire 过期时间（以秒为单位）
     * @memberof Cache
     */
    set(key, value, expire = timeout) {
      const stringData = JSON.stringify(this.hasStruct ? {
        value,
        time: Date.now(),
        expire: expire && !isNullOrUnDef(expire) ? new Date().getTime() + expire * 1000 : null,
      } : value)
      const stringifyValue = this.hasEncrypt ? this.encryption.encryptByAES(stringData) : stringData
      // const stringifyValue = stringData
      this.storage.setItem(this.getKey(key), stringifyValue)
    }

    /**
     * 读取缓存
     * @param {string} key
     * @param {*} def
     * @memberof Cache
     */
    get(key, def = null) {
      const val = this.storage.getItem(this.getKey(key))
      if (!val) return def

      try {
        const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val
        // const decVal = val
        const data = JSON.parse(decVal)
        if (this.hasStruct) {
          const { value, expire } = data
          if (isNullOrUnDef(expire) || expire >= new Date().getTime()) {
            return value
          }
        } else {
          return data
        }
        this.remove(key)
      } catch (e) {
        return def
      }
    }

    /**
     * 根据key删除缓存
     * @param {string} key
     * @memberof Cache
     */
    remove(key) {
      this.storage.removeItem(this.getKey(key))
    }

    /**
     * 删除本实例的所有缓存
     */
    clear() {
      this.storage.clear()
    }
  }
  return new WebStorage()
}

export { createStorage }